package com.qingxin.sys.smslib;

import java.io.IOException;

import org.smslib.AGateway;
import org.smslib.AGateway.GatewayStatuses;
import org.smslib.AGateway.Protocols;
import org.smslib.GatewayException;
import org.smslib.ICallNotification;
import org.smslib.IGatewayStatusNotification;
import org.smslib.IInboundMessageNotification;
import org.smslib.IOrphanedMessageNotification;
import org.smslib.IOutboundMessageNotification;
import org.smslib.InboundMessage;
import org.smslib.Message.MessageEncodings;
import org.smslib.Message.MessageTypes;
import org.smslib.OutboundMessage;
import org.smslib.SMSLibException;
import org.smslib.Service;
import org.smslib.TimeoutException;
import org.smslib.modem.SerialModemGateway;

public class SmsServer {
	
	private Service service;
	private SmsSetting setting;
	
	/**
	 * 启动服务
	 * @param setting
	 * @throws TimeoutException
	 * @throws SMSLibException
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public void startServer(SmsSetting setting) throws TimeoutException, SMSLibException, IOException, InterruptedException {
		this.setting = setting;
		SerialModemGateway gateway = new SerialModemGateway(
				setting.getId(),
				setting.getComPort(),
				setting.getBaudRate(),
				setting.getManufacturer(),
				setting.getModel());
		
		gateway.setInbound(true);
		gateway.setOutbound(true);
		
		gateway.setProtocol(Protocols.PDU);//发中文短信必须
		gateway.setSimPin(setting.getSimPin());
		
		InboundNotification inboundNotification = new InboundNotification();
		CallNotification callNotification = new CallNotification();
		GatewayStatusNotification statusNotification = new GatewayStatusNotification();
		OrphanedMessageNotification orphanedMessageNotification = new OrphanedMessageNotification();
		OutboundNotification outboundNotification = new OutboundNotification();
		
		service = Service.getInstance();
		service.S.SERIAL_POLLING = true;
		
		service.setInboundMessageNotification(inboundNotification);
		service.setCallNotification(callNotification);
		service.setGatewayStatusNotification(statusNotification);
		service.setOrphanedMessageNotification(orphanedMessageNotification);
		service.setOutboundMessageNotification(outboundNotification);
		
		service.addGateway(gateway);
		service.startService();
		
		System.out.println("SmsServer started.");
	}
	
	
	/**
	 * 停止服务
	 * @throws TimeoutException
	 * @throws GatewayException
	 * @throws SMSLibException
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public void stopServer() throws TimeoutException, GatewayException, SMSLibException, IOException, InterruptedException{
		service.stopService();
		System.out.println("SmsServer stoped.");
	}
	
	
	
	/**
	 * 发送短信
	 * @param phone
	 * @param message
	 * @return
	 * @throws TimeoutException
	 * @throws GatewayException
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public boolean send(String phone, String message) throws TimeoutException, GatewayException, IOException, InterruptedException  {
		OutboundMessage msg = new OutboundMessage(phone, message);
		msg.setEncoding(MessageEncodings.ENCUCS2);//发中文短信必须
		boolean state = service.sendMessage(msg);
		System.out.println("发送短信："+phone+";"+message+";state="+state);
		return state;
	}
	
	
//	/**
//	 * 读取短信
//	 * @return
//	 * @throws TimeoutException
//	 * @throws GatewayException
//	 * @throws IOException
//	 * @throws InterruptedException
//	 */
//	public List<InboundMessage> read() throws TimeoutException, GatewayException, IOException, InterruptedException{
//		List<InboundMessage> msgList = new ArrayList<>();
//		service.readMessages(msgList, MessageClasses.ALL);
//		for(InboundMessage msg : msgList){
//			System.out.println(msg);
//		}
//		return msgList;
//	}
	
	
	
	//入栈信息通知，也就是监听短信来了的类
	public class InboundNotification implements IInboundMessageNotification{
		@Override
		public void process(AGateway gateway, MessageTypes messageTypes, InboundMessage inboundMessage) {
			if(setting.isSmsLog()){
				if (messageTypes == MessageTypes.INBOUND){
					System.out.println(">>> New Inbound message detected from Gateway: " + gateway.getGatewayId());
				}else if (messageTypes == MessageTypes.STATUSREPORT){
					System.out.println(">>> New Inbound Status " + "Report message detected from Gateway: " + gateway.getGatewayId());
				}
				System.out.println(inboundMessage);
			}
			
			if (messageTypes == MessageTypes.INBOUND){
				String phone = inboundMessage.getOriginator();
				String message = inboundMessage.getText();
				
				System.out.println("收到短信："+phone+";"+message);
				
				SmsFactory.onReceivedSms(phone, message);
			}
			
			try {
				gateway.deleteMessage(inboundMessage);
			} catch (TimeoutException | GatewayException | IOException
					| InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	public class CallNotification implements ICallNotification{
		@Override
		public void process(AGateway gateway, String callerId) {
			if(setting.isSmsLog()){
				System.out.println(">>> New call detected from Gateway: " + gateway.getGatewayId() + " : " + callerId);
			}
		}
	}
	
	
	public class GatewayStatusNotification implements IGatewayStatusNotification{
		@Override
		public void process(AGateway gateway, GatewayStatuses oldStatus, GatewayStatuses newStatus) {
			if(setting.isSmsLog()){
				System.out.println(">>> Gateway Status change for " + gateway.getGatewayId() + ", OLD: " + oldStatus + " -> NEW: " + newStatus);
			}
		}
	}
	
	//不完整短信通知，比如很长的短信，被拆分成5个短信，smslib会自动整理成一个 完整的信息，然后通知短信监听器，
	//但是有可能因为网络原因，只过来3条，这三条短信就成了无人认领的孤儿，smslib判断孤儿的策略很简单，当n小时还没有被“认领”，该短信就被认为是孤儿，默认是72小时。
	public class OrphanedMessageNotification implements IOrphanedMessageNotification{
		@Override
		public boolean process(AGateway gateway, InboundMessage inboundmessage) {
			if(setting.isSmsLog()){
				System.out.println(">>> Orphaned message part detected from " + gateway.getGatewayId());
				System.out.println(inboundmessage);
			}
			// Since we are just testing, return FALSE and keep the orphaned message part.
			return false;
		}
	}
	
	
	public class OutboundNotification implements IOutboundMessageNotification{
		@Override
		public void process(AGateway gateway, OutboundMessage msg) {
			if(setting.isSmsLog()){
				System.out.println("Outbound handler called from Gateway: " + gateway.getGatewayId());
				System.out.println(msg);
			}
		}
	}
	
	
	
}
